/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <arkui/native_interface.h>
#include <arkui/native_node.h>
#include <arkui/native_node_napi.h>
#include <cstdint>
#include <string>
#include <cstdio>

#include <ace/xcomponent/native_interface_xcomponent.h>
#include <hilog/log.h>

#include "manager.h"


namespace NativeXComponentSample {
Manager Manager::manager_;

    Manager::~Manager() {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "~Manager");
        for (auto iter = nativeXComponentMap_.begin(); iter != nativeXComponentMap_.end(); ++iter) {
            if (iter->second != nullptr) {
//                delete iter->second;
                iter->second = nullptr;
            }
        }
        nativeXComponentMap_.clear();
    
        for (auto iter = containerMap_.begin(); iter != containerMap_.end(); ++iter) {
            if (iter->second != nullptr) {
                delete iter->second;
                iter->second = nullptr;
            }
        }
        containerMap_.clear();
    }

    napi_value Manager::CreateNativeNode(napi_env env, napi_callback_info info) {
        if ((env == nullptr) || (info == nullptr)) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode env or info is null");
            return nullptr;
        }

        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode  1111");

        size_t argCnt = 2;
        napi_value args[2] = { nullptr };
        if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode napi_get_cb_info failed");
        }
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "argCnt  : %{public}d", argCnt);
        if (argCnt < 1) {
            napi_throw_type_error(env, NULL, "Wrong number of arguments");
            return nullptr;
        }
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "args 1  : %{public}p", args[0]);
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "args 2  : %{public}p", args[1]);
        napi_valuetype valuetype;
        if (napi_typeof(env, args[0], &valuetype) != napi_ok) {
            napi_throw_type_error(env, NULL, "napi_typeof failed");
            return nullptr;
        }

        if (valuetype != napi_string) {
            napi_throw_type_error(env, NULL, "Wrong type of arguments");
            return nullptr;
        }
        napi_valuetype valuetype1;
        auto typeId = napi_typeof(env, args[1], &valuetype1);
        if (typeId != napi_ok) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "napi_typeof error  : %{public}d", typeId);
            return nullptr;
       }
       if (valuetype1 != napi_object) {
            napi_throw_type_error(env, NULL, "Wrong type of arguments of 1");
            return nullptr;
        }

        char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
        constexpr uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
        size_t length;
        if (napi_get_value_string_utf8(env, args[0], idStr, idSize, &length) != napi_ok) {
            napi_throw_type_error(env, NULL, "napi_get_value_int64 failed");
            return nullptr;
        }
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode  2222 %{public}s", idStr);
    
        napi_value properties = nullptr;
        napi_get_property_names(env, args[1], &properties);
        uint32_t length1 = 0;
        napi_get_array_length(env, properties, &length1);
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "get property:   %{public}d", length1);
        for (uint32_t i = 0; i < length1; i++) {
             napi_value propertyName = nullptr;
             napi_get_element(env, properties, i, &propertyName);
             char idStr[100] = {'\0'};
             constexpr uint64_t idSize = 100;
             size_t length;
             napi_get_value_string_utf8(env, propertyName, idStr, idSize, &length);
             OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "get property:  %{public}s", idStr);
        }
    

        auto manager = Manager::GetInstance();
        if (manager == nullptr) {
            return nullptr;
        }

        OH_NativeXComponent *component = manager->GetNativeXComponent(idStr);
        if (component == nullptr) {
            return nullptr;
        }

        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode  3333333");
        ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1*>(OH_ArkUI_GetNativeAPI(ARKUI_NATIVE_NODE, 1));
        if (nodeAPI != nullptr) {
            OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode  34444");
            if (nodeAPI->createNode != nullptr && nodeAPI->addChild != nullptr) {
                OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "OnSurfaceCreatedCB  222--1");
            

                // ArkUI_NativeNodeAPI_1* nativeNodeApi =
                // reinterpret_cast<ArkUI_NativeNodeAPI_1*>(OH_ArkUI_GetNativeAPI(ARKUI_NATIVE_NODE, 1));

            
//                ArkUI_NodeHandle textarea = nodeAPI->createNode(ARKUI_NODE_TEXT_AREA);
//                                nodeAPI->setAttribute(textarea, NODE_WIDTH, "300");
//                                nodeAPI->setAttribute(textarea, NODE_HEIGHT, "50");
//                                nodeAPI->setAttribute(textarea, NODE_TEXT_INPUT_TEXT, "");
//                                nodeAPI->setAttribute(textarea, NODE_BACKGROUND_COLOR, "#FF0000FF");
//                nodeAPI->applyModifierFinish(textarea);
            
//                
                ArkUI_NodeHandle stack = nodeAPI->createNode(ARKUI_NODE_STACK);
     //ArkUI_NumberValue imageSizeStyle[] = { {.i32 = static_cast<int32_t>(ARKUI_IMAGE_SIZE_COVER) } };
     //ArkUI_AttributeItem item = { .value = imageSizeStyle, .size = 1};
    // nodeAPI->setAttribute(stack, NODE_BACKGROUND_IMAGE_SIZE_WITH_STYLE, &item);

    // ArkUI_NumberValue value[] = { { .i32 = ARKUI_ALIGNMENT_CENTER } };
     //ArkUI_AttributeItem item = { value, sizeof(value) / sizeof(ArkUI_NumberValue) };
    // nodeAPI->setAttribute(stack, NODE_STACK_ALIGN_CONTENT, &item);
     //auto alignContentItem = nodeAPI->getAttribute(stack, NODE_STACK_ALIGN_CONTENT);
    // auto alignContent = alignContentItem->value[0].i32;
            
            
     //auto blurdStyle = imageSizeStyleItem->value[0].i32;
                ArkUI_NumberValue widthValue[] = { {.f32 = 300} };
                ArkUI_AttributeItem widthItem = { .value = widthValue , .size = 1 };
                nodeAPI->setAttribute(stack, NODE_WIDTH, &widthItem);
                ArkUI_NumberValue heightValue[] = { {.f32 = 300} };
                ArkUI_AttributeItem heightItem = { .value = heightValue , .size = 1 };
                nodeAPI->setAttribute(stack, NODE_HEIGHT, &heightItem);
                ArkUI_NumberValue backgroundColorValue[] = { {.u32 = 0xFF8eff64} };
                ArkUI_AttributeItem backgroundColorItem = { .value = backgroundColorValue , .size = 1 };
              nodeAPI->setAttribute(stack, NODE_BACKGROUND_COLOR, &backgroundColorItem);
//                ArkUI_NumberValue backGroundImageSizeValue[] = { {.f32 = 200},{.f32 = 10} };
//               ArkUI_AttributeItem backGroundImageSizeItem = { .value = backGroundImageSizeValue , .size = 2 };
//               nodeAPI->setAttribute(stack, NODE_BACKGROUND_IMAGE_SIZE,&backGroundImageSizeItem);
                
              //  ArkUI_NumberValue imageSizeStyle[] = { {.i32 = static_cast<int32_t>(ARKUI_IMAGE_SIZE_COVER) } };
              ////  ArkUI_AttributeItem imageSizeStyleItem = { .value = imageSizeStyle , .size = 2 };
              //  nodeAPI->setAttribute(stack, NODE_BACKGROUND_IMAGE_SIZE_WITH_STYLE,&imageSizeStyleItem);
//                ArkUI_AttributeItem backGroundImageItem = { .string = "/pages/icon.png" };
//                nodeAPI->setAttribute(stack, NODE_BACKGROUND_IMAGE,&backGroundImageItem);
               // ArkUI_NumberValue blurStyle[] = { { .i32 = static_cast<int32_t>(ARKUI_BLUR_STYLE_THICK)}};
                //ArkUI_AttributeItem blurStyleitem = { .value = blurStyle, .size = 1};
           // nodeAPI->setAttribute(stack, NODE_BACKGROUND_BLUR_STYLE,&blurStyleitem);
             
                //nodeAPI->setAttribute(stack, NODE_SCALE_TRANSITION,&scaleTransitionItem);
                /*ArkUI_NumberValue transformCenterItem[] = { 0, 0, 0, 0, 0.5};
                ArkUI_AttributeItem centerTransitionItem = { .value = transformCenterItem , .size = 5 }; 
                nodeAPI->setAttribute(stack, NODE_TRANSFORM_CENTER , &centerTransitionItem);*/
              /*  ArkUI_NumberValue rotateTransition[] = { -100, -100, -100, 180, 100, { .i32 = 300},{ .i32 = static_cast<int32_t>(ARKUI_CURVE_SHARP)},{ .i32 = -1500},{ .i32 = -3},{ .i32 = ARKUI_ANIMATION_PLAY_MODE_ALTERNATE}};
                ArkUI_AttributeItem rotateTransitionItem = { .value = rotateTransition , .size = 10 };   
                nodeAPI->setAttribute(stack, NODE_ROTATE_TRANSITION,&rotateTransitionItem);
                ArkUI_NumberValue opacityTransition[] = { 0, { .i32 = 3000},{ .i32 = static_cast<int32_t>(ARKUI_CURVE_SHARP)}, { .i32 = -1500},{ .i32 = -1},{ .i32 = ARKUI_ANIMATION_PLAY_MODE_ALTERNATE}};
                ArkUI_AttributeItem opacityTransitionItem = { .value = opacityTransition , .size = 6 };   
                nodeAPI->setAttribute(stack, NODE_OPACITY_TRANSITION,&opacityTransitionItem);*/
              /*  ArkUI_NumberValue scaleTransition[] = { 0.0f, 0.0f, 0.0f, { .i32 = 3000},{ .i32 = static_cast<int32_t>(ARKUI_CURVE_SHARP)}};
                ArkUI_AttributeItem scaleTransitionItem = { .value = scaleTransition , .size = 5 };   
                nodeAPI->setAttribute(stack, NODE_SCALE_TRANSITION,&scaleTransitionItem);
                ArkUI_NumberValue translateTransition[] = { 300.0f, 100.0f, 0.0f, { .i32 = 3000},{ .i32 = static_cast<int32_t>(ARKUI_CURVE_SHARP)}};
                ArkUI_AttributeItem translateTransitionItem = { .value = translateTransition , .size = 5 };
                nodeAPI->setAttribute(stack, NODE_TRANSLATE_TRANSITION,&translateTransitionItem);*/


                 //nativeNodeApi->setAttribute(nodeHandle, NODE_IMAGE_COLOR_FILTER , &item);

                //nodeAPI->setAttribute(stack, NODE_TRANSLATE_TRANSITION,"1 30 2");
               /// nodeAPI->setAttribute(stack, NODE_BACKGROUND_BLUR_STYLE,"THIN");
            
           // nodeAPI->setAttribute(stack, NODE_OPACITY_TRANSITION,"0 3000 ease");
            
            
           //nodeAPI->setAttribute(stack, NODE_ROTATE_TRANSITION,"0 0 1 0 180 3000 ease");
           // nodeAPI->setAttribute(stack, NODE_SCALE_TRANSITION,"0 0 0 3000 ease");
          //  
                  /*           ArkUI_NodeHandle image = nodeAPI->createNode(ARKUI_NODE_IMAGE);
                             ArkUI_NumberValue imageWidthValue[] = { {.f32 = 300} };
                             ArkUI_AttributeItem imageWidthItem = { .value = imageWidthValue , .size = 1 };
                             nodeAPI->setAttribute(image, NODE_WIDTH, &imageWidthItem);
                             ArkUI_NumberValue imageHeightValue[] = { {.f32 = 300} };
                             ArkUI_AttributeItem imageHeightItem = { .value = imageHeightValue , .size = 1 };
                             nodeAPI->setAttribute(image, NODE_HEIGHT, &imageHeightItem);
                             ArkUI_AttributeItem imageSrcItem = { .string = "/pages/icon.png" };
                             nodeAPI->setAttribute(image, NODE_IMAGE_SRC, &imageSrcItem);
                                         ArkUI_AttributeItem imageAltItem = { .string = "/pages/icon.png" };
                                         nodeAPI->setAttribute(image, NODE_IMAGE_ALT, &imageAltItem);
            ArkUI_NumberValue objectFitValue[] = { {.i32 = static_cast<int>(ARKUI_OBJECT_FIT_NONE)}};
     //ArkUI_NumberValue objectFitValue[] = { {.i32 = static_cast<int>(ARKUI_OBJECT_FIT_CONTAIN)}};
                            ArkUI_AttributeItem objectFitItem = {.value = objectFitValue, .size = 1};
                            nodeAPI->setAttribute(image, NODE_IMAGE_OBJECT_FIT, &objectFitItem);
            
                            ArkUI_AttributeItem objectRepeatItem = {.value = objectFitValue, .size = 1};
                            nodeAPI->setAttribute(image, NODE_IMAGE_OBJECT_REPEAT, &objectRepeatItem);
            
                 ArkUI_NumberValue repeatValue[] = { { .i32 = static_cast<int32_t>(ARKUI_IMAGE_REPEAT_X) } };
                 ArkUI_AttributeItem repeatItem = { .value = repeatValue, .size = 1};
                 nodeAPI->setAttribute(image, NODE_IMAGE_OBJECT_REPEAT , &repeatItem);
            //1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0
                     /*        ArkUI_NumberValue filterValue[] = { {.i32 = 1}, {.i32 = 0}, {.i32 = 0}, {.i32 = 0}, {.i32 = 0}, {.i32 = 0}, {.i32
                             = 0}, {.i32 = 0}, {.i32 = 0}, {.i32 = 0}, {.i32 = 0}, {.i32 = 1}, {.i32 = 0}, {.i32 = 0}, {.i32 = 0}, {.i32 =
                             1}, {.i32 = 0}, {.i32 = 0}, {.i32 = 0}, {.i32 = 0} };
                             ArkUI_AttributeItem item = { .value = filterValue, .size = 20};
            nodeAPI->setAttribute(image, NODE_IMAGE_COLOR_FILTER, &item);
           /* nodeAPI->registerNodeEvent(image,NODE_IMAGE_ON_COMPLETE,1);
            nodeAPI->registerNodeEventReceiver([](ArkUI_NodeEvent* event){
                OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "wchtest on image complete %{public}d",event->componentEvent.data[0].i32);
            });
                        nodeAPI->registerNodeEvent(image,NODE_IMAGE_ON_ERROR,1);
                        nodeAPI->registerNodeEventReceiver([](ArkUI_NodeEvent* event){
                            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "wchtest on image error %{public}d",event->componentEvent.data[0].i32);
                        });*/
            /*
                         nodeAPI->registerNodeEvent(image,NODE_ON_CLICK,4);
                                    nodeAPI->registerNodeEventReceiver([](ArkUI_NodeEvent* event){
                                        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "wchtest on image click");
                                    });
             nodeAPI->registerNodeEvent(image,NODE_IMAGE_ON_COMPLETE,1);
                        nodeAPI->registerNodeEventReceiver([](ArkUI_NodeEvent* event){
                            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "wchtest on image complete %{public}d",event->componentEvent.data[0].i32);
                        });
                                    nodeAPI->registerNodeEvent(image,NODE_IMAGE_ON_ERROR,2);
                                    nodeAPI->registerNodeEventReceiver([](ArkUI_NodeEvent* event){
                                        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "wchtest on image error %{public}d",event->componentEvent.data[0].i32);
                                    });
                                               nodeAPI->registerNodeEvent(image,NODE_IMAGE_ON_ERROR,3);
                                               nodeAPI->registerNodeEventReceiver([](ArkUI_NodeEvent* event){
                                                   OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "wchtest on image error %{public}d",event->componentEvent.data[0].i32);
                                               });*/
//                            ArkUI_NodeHandle text = nodeAPI->createNode(ARKUI_NODE_TEXT);
//                            ArkUI_NumberValue textWidthValue[] = { {.f32 = 300} };
//                            ArkUI_AttributeItem textWidthItem = { .value = textWidthValue , .size = 1 };
//                            nodeAPI->setAttribute(text, NODE_WIDTH, &textWidthItem);
//                            ArkUI_NumberValue textHeightValue[] = { {.f32 = 100} };
//                            ArkUI_AttributeItem textHeightItem = { .value = textHeightValue , .size = 1 };
//                            nodeAPI->setAttribute(text, NODE_HEIGHT, &textHeightItem);
                            // ArkUI_NumberValue textbackgroundColorValue[] = { {.u32 = 0xFFffff77} };
                                         //ArkUI_AttributeItem textbackgroundColorItem = { .value = textbackgroundColorValue , .size = 1 };
                                         //nodeAPI->setAttribute(text, NODE_BACKGROUND_COLOR, &textbackgroundColorItem);
                           // ArkUI_AttributeItem arkUI_AttributeItem = {.string = "这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本这是一段测试文本"};
                            //nodeAPI->setAttribute(text, NODE_TEXT_CONTENT, &arkUI_AttributeItem);
               // ArkUI_NumberValue ali
            
           // gnMent[] = {{.i32 = static_cast<int32_t>(ARKUI_TEXT_ALIGNMENT_CENTER)}};
               // ArkUI_AttributeItem alignitem = {.value = alignMent, .size = 1};
         //   nodeAPI->setAttribute(text, NODE_TEXT_ALIGN, &alignitem);
                            //ArkUI_NumberValue lineHeight[] = { 10 };
                            //ArkUI_AttributeItem lineHeightiItem = { .value = lineHeight, .size = 1};
                            //nodeAPI->setAttribute(text, NODE_TEXT_LINE_HEIGHT , &lineHeightiItem);
                            //ArkUI_NumberValue letterSpacing[] = { 40 };
                            //ArkUI_AttributeItem letterSpcaingitem = { .value = letterSpacing, .size = 1};
                            //nodeAPI->setAttribute(text, NODE_TEXT_LETTER_SPACING , &letterSpcaingitem);
                            //ArkUI_NumberValue maxLine[] = { { .i32 = 2 } };
                            //ArkUI_AttributeItem item = { .value = maxLine, .size = 1};
                            //nodeAPI->setAttribute(text, NODE_TEXT_MAX_LINES , &item);
                            //ArkUI_NumberValue textOverFlow[] = { { .i32 = static_cast<int32_t>(ARKUI_TEXT_OVERFLOW_MARQUEE) } };
                            //ArkUI_AttributeItem textOveFlowItem = { .value = textOverFlow, .size = 1};
                            //nodeAPI->setAttribute(text,NODE_TEXT_OVERFLOW , &textOveFlowItem);
                            //ArkUI_NumberValue textIndent[] = {100};
                            //ArkUI_AttributeItem indentItem = {.value = textIndent, .size = 1};
                            //nodeAPI->setAttribute(text, NODE_TEXT_INDENT, &indentItem);
//                            ArkUI_NodeHandle span = nodeAPI->createNode(ARKUI_NODE_SPAN);
//                            //ArkUI_AttributeItem spanWidthItem = { .value = textWidthValue , .size = 1 };
//                            //nodeAPI->setAttribute(span, NODE_WIDTH, &spanWidthItem);
//                            ArkUI_AttributeItem spanItem = { .string = "测试测试测试测试测试测试测试测试" };
//                            nodeAPI->setAttribute(span, NODE_SPAN_CONTENT , &spanItem);
//            
//                            ArkUI_NumberValue spanWidthValue[] = { {.f32 = 300} };
//                            ArkUI_AttributeItem spanWidthItem = { .value = spanWidthValue , .size = 1 };
//                            nodeAPI->setAttribute(span, NODE_WIDTH, &spanWidthItem);
//                            ArkUI_NumberValue spanHeightValue[] = { {.f32 = 300} };
//                            ArkUI_AttributeItem imageHeightItem = { .value = spanHeightValue , .size = 1 };
//                            nodeAPI->setAttribute(span, NODE_HEIGHT, &imageHeightItem);
//            
//                            ArkUI_NumberValue value[] = { {.i32 = 0} };
//                            ArkUI_AttributeItem item = { value, sizeof(value)/sizeof(ArkUI_NumberValue) };
//                            nodeAPI->setAttribute(span, NODE_CLIP, &item);
//            
//                            ArkUI_NumberValue spanFontSizeValue[] = { 40 };
//                            ArkUI_AttributeItem spanFontSizeItem = { .value = spanFontSizeValue, .size = 1 };
//                            nodeAPI->setAttribute(span, NODE_FONT_SIZE, &spanFontSizeItem);
//            
//                            ArkUI_NumberValue lineHeight[] = { 40 };
//                            ArkUI_AttributeItem lineHeightItem = { .value = lineHeight, .size = 1};
//                            nodeAPI->setAttribute(span, NODE_TEXT_LINE_HEIGHT , &lineHeightItem);
//                            ArkUI_NumberValue spanWeightValue[] = { {.i32 = ARKUI_FONT_WEIGHT_BOLD} };
//                            ArkUI_AttributeItem spanWeightItem = { spanWeightValue, 1 };
//                            nodeAPI->setAttribute(span, NODE_FONT_WEIGHT, &spanWeightItem);
//                            ArkUI_NumberValue spanDecorationValue[] = { {.i32 = ARKUI_TEXT_DECORATION_TYPE_UNDERLINE}};
//                            ArkUI_AttributeItem spanDecorationItem = { spanDecorationValue, 1 };
//                            nodeAPI->setAttribute(span, NODE_TEXT_DECORATION, &spanDecorationItem);
//
//                            ArkUI_NodeHandle imageSpan = nodeAPI->createNode(ARKUI_NODE_IMAGE_SPAN);
//                            ArkUI_NumberValue imageSpanWidthValue[] = { {.f32 = 50} };
//                            ArkUI_AttributeItem imageSpanWidthItem = { .value = imageSpanWidthValue , .size = 1 };
//                            nodeAPI->setAttribute(imageSpan, NODE_WIDTH, &imageSpanWidthItem);
//                            ArkUI_NumberValue imageSpanHeightValue[] = { {.f32 = 80} };
//                            ArkUI_AttributeItem imageSpanHeightItem = { .value = imageSpanHeightValue , .size = 1 };
//                            nodeAPI->setAttribute(imageSpan, NODE_HEIGHT, &imageSpanHeightItem);
//                            ArkUI_AttributeItem imageSpanSrcItem = { .string = "/pages/icon.png"};
//                            nodeAPI->setAttribute(imageSpan, NODE_IMAGE_SPAN_SRC, &imageSpanSrcItem);
//                            ArkUI_NumberValue alignValue[] = { {.i32 = static_cast<int32_t>(ARKUI_IMAGE_SPAN_ALIGNMENT_BASELINE) } };
//                            ArkUI_AttributeItem imageSpanItem = {.value = alignValue, .size = 1};
//                            nodeAPI->setAttribute(imageSpan, NODE_IMAGE_SPAN_VERTICAL_ALIGNMENT , &imageSpanItem);
//                            ArkUI_NumberValue imageSpanObjectFitValue[] = { { .i32 = static_cast<int32_t>(ARKUI_OBJECT_FIT_CONTAIN) } };
//                            ArkUI_AttributeItem imageSpanObjectFitItem = { .value = imageSpanObjectFitValue, .size = 1};
//                            nodeAPI->setAttribute(imageSpan, NODE_IMAGE_OBJECT_FIT , &imageSpanObjectFitItem);
//                            
//                            ArkUI_NodeHandle span2 = nodeAPI->createNode(ARKUI_NODE_SPAN);
//                            ArkUI_AttributeItem spanItem2 = { .string = "121424324244324324" };
//                            nodeAPI->setAttribute(span2, NODE_SPAN_CONTENT , &spanItem2);
//            
//                            ArkUI_NodeHandle calendarPicker = nodeAPI->createNode(ARKUI_NODE_CALENDAR_PICKER);
//            
//                            ArkUI_NumberValue calenderWidthValue[] = { {.f32 = 200} };
//                            ArkUI_AttributeItem calendarWidthItem = { .value = calenderWidthValue , .size = 1 };
//                            nodeAPI->setAttribute(calendarPicker, NODE_WIDTH, &calendarWidthItem);
//                            ArkUI_NumberValue calendarHeightValue[] = { {.f32 = 200} };
//                            ArkUI_AttributeItem calendarHeightItem = { .value = calendarHeightValue , .size = 1 };
//                            nodeAPI->setAttribute(calendarPicker, NODE_HEIGHT, &calendarHeightItem);
//                            ArkUI_NumberValue hintRadiusValue[] = { 0.0f };
//                            ArkUI_AttributeItem hintRadiusItem = { hintRadiusValue, sizeof(hintRadiusValue) / sizeof(ArkUI_NumberValue) };
//                            nodeAPI->setAttribute(calendarPicker, NODE_CALENDAR_PICKER_HINT_RADIUS, &hintRadiusItem);
//                            auto getCalenderRadiusItem = nodeAPI->getAttribute(calendarPicker, NODE_CALENDAR_PICKER_HINT_RADIUS);
//                            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "wchtest", "NODE_CALENDAR_PICKER_HINT_RADIUS radius %{public}f",getCalenderRadiusItem->value[0].f32);
//                                      
//                            nodeAPI->resetAttribute(calendarPicker, NODE_CALENDAR_PICKER_HINT_RADIUS);
//                            auto getResetRadiusItem = nodeAPI->getAttribute(calendarPicker, NODE_CALENDAR_PICKER_HINT_RADIUS);
//                            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "wchtest", "reset NODE_CALENDAR_PICKER_HINT_RADIUS radius %{public}f",getResetRadiusItem->value[0].f32);
//            
//                            ArkUI_NumberValue dvalue[] = { { .u32 = 2028 }, { .u32 = 1 }, { .u32 = 1 } };
//                            ArkUI_AttributeItem sitem = { dvalue, sizeof(dvalue) / sizeof(ArkUI_NumberValue) };
//                            nodeAPI->setAttribute(calendarPicker, NODE_CALENDAR_PICKER_SELECTED_DATE, &sitem);
//                            auto getCalenderSelectedItem = nodeAPI->getAttribute(calendarPicker, NODE_CALENDAR_PICKER_SELECTED_DATE);
//                            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "wchtest", "NODE_CALENDAR_PICKER_SELECTED_DATE year %{public}u month %{public}u, day %{public}u",getCalenderSelectedItem->value[0].u32,getCalenderSelectedItem->value[1].u32,getCalenderSelectedItem->value[2].u32);
//                                      
//                            nodeAPI->resetAttribute(calendarPicker, NODE_CALENDAR_PICKER_SELECTED_DATE);
//                            auto getResetCalenderSelectedItem = nodeAPI->getAttribute(calendarPicker, NODE_CALENDAR_PICKER_SELECTED_DATE);
//                            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "wchtest", "reset NODE_CALENDAR_PICKER_SELECTED_DATE year %{public}u month %{public}u, day %{public}u",getResetCalenderSelectedItem->value[0].u32,getResetCalenderSelectedItem->value[1].u32,getResetCalenderSelectedItem->value[2].u32);
//
//                            ArkUI_NumberValue edgeAlimentValue[] = { { .i32 = static_cast<int32_t>(ARKUI_CALENDAR_ALIGNMENT_START) }, 10.0f, 100.0f };
//                            ArkUI_AttributeItem edgeAlimentitem = { edgeAlimentValue, sizeof(edgeAlimentValue) / sizeof(ArkUI_NumberValue) };
//                            nodeAPI->setAttribute(calendarPicker, NODE_CALENDAR_PICKER_EDGE_ALIGNMENT, &edgeAlimentitem);
//                            auto getCalenderEdgeItem = nodeAPI->getAttribute(calendarPicker, NODE_CALENDAR_PICKER_EDGE_ALIGNMENT);
//                            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "wchtest", "NODE_CALENDAR_PICKER_EDGE_ALIGNMENT alignType %{public}d offsetX %{public}f, offsetY %{public}f",getCalenderEdgeItem->value[0].i32,getCalenderEdgeItem->value[1].f32,getCalenderEdgeItem->value[2].f32);
//                          
//                            nodeAPI->resetAttribute(calendarPicker, NODE_CALENDAR_PICKER_EDGE_ALIGNMENT);
//                            auto getResetCalenderEdgeItem = nodeAPI->getAttribute(calendarPicker, NODE_CALENDAR_PICKER_EDGE_ALIGNMENT);
//                            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "wchtest", "reset NODE_CALENDAR_PICKER_EDGE_ALIGNMENT alignType %{public}d offsetX %{public}f, offsetY %{public}f",getResetCalenderEdgeItem->value[0].i32,getResetCalenderEdgeItem->value[1].f32,getResetCalenderEdgeItem->value[2].f32);
//
//            
//                            ArkUI_NumberValue calendarPickerTextValue[] = { { .u32 = 0x000000ff }, 26.0f, { .i32 =
//                            static_cast<int32_t>(ARKUI_FONT_WEIGHT_W200)} };
//                            ArkUI_AttributeItem calendarPickerTextItem = { calendarPickerTextValue, sizeof(calendarPickerTextValue) / sizeof(ArkUI_NumberValue) };
//                            nodeAPI->setAttribute(calendarPicker, NODE_CALENDAR_PICKER_TEXT_STYLE, &calendarPickerTextItem);
//                            auto getCalenderTextItem = nodeAPI->getAttribute(calendarPicker, NODE_CALENDAR_PICKER_TEXT_STYLE);
//                            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "wchtest", "NODE_CALENDAR_PICKER_TEXT_STYLE textcolor %{public}u textsize %{public}f, fontWeight %{public}d",getCalenderTextItem->value[0].u32,getCalenderTextItem->value[1].f32,getCalenderTextItem->value[2].i32);
//                          
//                            nodeAPI->resetAttribute(calendarPicker, NODE_CALENDAR_PICKER_TEXT_STYLE);
//                            auto getResetCalenderTextItem = nodeAPI->getAttribute(calendarPicker, NODE_CALENDAR_PICKER_TEXT_STYLE);
//                            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "wchtest", "reset NODE_CALENDAR_PICKER_TEXT_STYLE textcolor %{public}u textsize %{public}f, fontWeight %{public}d",getCalenderTextItem->value[0].u32,getCalenderTextItem->value[1].f32,getCalenderTextItem->value[2].i32);
//
//                            nodeAPI->registerNodeEvent(calendarPicker,NODE_CALENDAR_PICKER_EVENT_ON_CHANGE,3);
//                            nodeAPI->registerNodeEventReceiver([](ArkUI_NodeEvent* event){
//                                 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "wchtest on ON_CHANGE year %{public}u month %{public}u  day %{public}u",event->componentEvent.data[0].u32, event->componentEvent.data[1].u32, event->componentEvent.data[2].u32);
//                            });
//                            //nodeAPI->setAttribute(text, NODE_IMAGE_SRC, "/pages/icon.png");
//                            //nodeAPI->setAttribute(text, NODE_IMAGE_COLOR_FILTER,"1 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1");
//                            //nodeAPI->setAttribute(text, NODE_BACKGROUND_COLOR, "#0F008080");
//                            //nodeAPI->setAttribute(text, NODE_FONT_SIZE,"16fp");
//                            //nodeAPI->setAttribute(text, NODE_FONT_WEIGHT,"normal");
//                            //nodeAPI->setAttribute(text, NODE_FONT_WEIGHT,"");
//                            //nodeAPI->setAttribute(text, NODE_TRANSLATE_TRANSITION,"100 100 0 ease");*/
//                           
//                            //nodeAPI->applyModifierFinish(text);
//           //  nodeAPI->addChild(stack, image);
//           nodeAPI->addChild(text, span);
//           nodeAPI->addChild(text, imageSpan);
//           nodeAPI->addChild(text, span2);
           // nodeAPI->addChild(stack, calendarPicker);
            ArkUI_NodeHandle tsStackNode;
            auto result = OH_ArkUI_GetNodeHandleFromNapiValue(env, args[1], &tsStackNode);
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "use arkts1111:  %{public}d", result);
            if (result == 0) {
                OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "use arkts");
                OH_NativeXComponent_AttachNativeRootNode(component, tsStackNode);
            } else {
                OH_NativeXComponent_AttachNativeRootNode(component, stack);
            }
            //nodeAPI->applyModifierFinish(stack);
               // OH_NativeXComponent_MarkDirtyContainer(component, XComponent_NodeDirtyFlag::NEED_MEASURE);
//                OH_NativeXComponent_MarkDirtyContainer(component, XComponent_NodeDirtyFlag::NEED_LAYOUT);
            }
        }
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode  555");
        return nullptr;
    }


    napi_value Manager::UpdateNativeNode(napi_env env, napi_callback_info info) {

        if ((env == nullptr) || (info == nullptr )) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "UpdateNativeNode env or info is null");
            return nullptr;
        }

        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "UpdateNativeNode  1111");

        size_t argCnt = 1;
        napi_value args[1] = {nullptr};
        if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "UpdateNativeNode napi_get_cb_info failed");
        }

        if (argCnt != 1) {
            napi_throw_type_error(env, NULL, "Wrong number of arguments");
            return nullptr;
        }

        napi_valuetype valuetype;
        if (napi_typeof(env, args[0], &valuetype) != napi_ok) {
            napi_throw_type_error(env, NULL, "napi_typeof failed");
            return nullptr;
        }

        if (valuetype != napi_string) {
            napi_throw_type_error(env, NULL, "Wrong type of arguments");
            return nullptr;
        }

        char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
        constexpr uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
        size_t length;
        if (napi_get_value_string_utf8(env, args[0], idStr, idSize, &length) != napi_ok) {
            napi_throw_type_error(env, NULL, "napi_get_value_int64 failed");
            return nullptr;
        }
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "CreateNativeNode  1111 %{public}s", idStr);

        auto manager = Manager::GetInstance();
        if (manager == nullptr) {
            return nullptr;
        }

        OH_NativeXComponent *component = manager->GetNativeXComponent(idStr);
        if (component == nullptr) {
            return nullptr;
        }


        if ((env == nullptr) || (info == nullptr || component == nullptr)) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "GetContext env or info is null");
            return nullptr;
        }
    
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "UpdateNativeNode  1111");
        ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1*>(OH_ArkUI_GetNativeAPI(ARKUI_NATIVE_NODE, 1));
        if (nodeAPI != nullptr) {
            OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "UpdateNativeNode  222");
    
            if (nodeAPI->createNode != nullptr && nodeAPI->addChild != nullptr) {
                OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "UpdateNativeNode  222--1");
    
//                const ArkUICommonModifierAPI *modifier = nodeAPI->GetCommonModifier();
//    
//                ArkUI_NodeHandle text1 = nodeAPI->GetNodeById(100);
//                ArkUI_NodeHandle text2 = nodeAPI->GetNodeById(102);
//                ArkUI_NodeHandle text3 = nodeAPI->GetNodeById(104);
//                ArkUI_NodeHandle stack = nodeAPI->GetNodeById(105);
//            
//                modifier->SetWidth(text2, 0.7, 3, nullptr);   // 100 percent
//                modifier->SetHeight(text2, 55, 0, nullptr); // px
//                modifier->SetBackgroundColor(text2, 0xff00ff00);
//            
//                nodeAPI->RemoveChild(stack, text1);
//                nodeAPI->RemoveChild(stack, text3);
//                OH_NativeXComponent_MarkDirtyContainer(component, 1 << 9);
            }
        }
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "UpdateNativeNode  333");
        return nullptr;
    }


    napi_value Manager::GetContext(napi_env env, napi_callback_info info) {
        if ((env == nullptr) || (info == nullptr)) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "GetContext env or info is null");
            return nullptr;
        }

        size_t argCnt = 1;
        napi_value args[1] = {nullptr};
        if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "GetContext napi_get_cb_info failed");
        }

        if (argCnt != 1) {
            napi_throw_type_error(env, NULL, "Wrong number of arguments");
            return nullptr;
        }

        napi_valuetype valuetype;
        if (napi_typeof(env, args[0], &valuetype) != napi_ok) {
            napi_throw_type_error(env, NULL, "napi_typeof failed");
            return nullptr;
        }

        if (valuetype != napi_number) {
            napi_throw_type_error(env, NULL, "Wrong type of arguments");
            return nullptr;
        }

        int64_t value;
        if (napi_get_value_int64(env, args[0], &value) != napi_ok) {
            napi_throw_type_error(env, NULL, "napi_get_value_int64 failed");
            return nullptr;
        }

        napi_value exports;
        if (napi_create_object(env, &exports) != napi_ok) {
            napi_throw_type_error(env, NULL, "napi_create_object failed");
            return nullptr;
        }

        return exports;
    }

    void Manager::Export(napi_env env, napi_value exports) {
        if ((env == nullptr) || (exports == nullptr)) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "Export: env or exports is null");
            return;
        }

        napi_value exportInstance = nullptr;
        if (napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "Export: napi_get_named_property fail");
            return;
        }

        OH_NativeXComponent *nativeXComponent = nullptr;
        if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager", "Export: napi_unwrap fail");
            return;
        }
   
        char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
        uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
        if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) !=
            OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Manager",
                         "Export: OH_NativeXComponent_GetXComponentId fail");
            return;
        }

        std::string id(idStr);
        auto manager = Manager::GetInstance();
        if ((manager != nullptr) && (nativeXComponent != nullptr)) {
            manager->SetNativeXComponent(id, nativeXComponent);
            auto container = manager->GetContainer(id);
            if (container != nullptr) {
                container->RegisterCallback(nativeXComponent);
                //            container->Export(env, exports);
            }
        }
    }

    void Manager::SetNativeXComponent(std::string & id, OH_NativeXComponent * nativeXComponent) {
        if (nativeXComponent == nullptr) {
            return;
        }

        if (nativeXComponentMap_.find(id) == nativeXComponentMap_.end()) {
            nativeXComponentMap_[id] = nativeXComponent;
            return;
        }

        if (nativeXComponentMap_[id] != nativeXComponent) {
            OH_NativeXComponent *tmp = nativeXComponentMap_[id];
            delete tmp;
            tmp = nullptr;
            nativeXComponentMap_[id] = nativeXComponent;
        }
    }

    OH_NativeXComponent* Manager::GetNativeXComponent(const std::string &id) {
        return nativeXComponentMap_[id];
    }

    Container *Manager::GetContainer(std::string & id) {
        if (containerMap_.find(id) == containerMap_.end()) {
            Container *instance = Container::GetInstance(id);
            containerMap_[id] = instance;
            return instance;
        }

        return containerMap_[id];
    }
} // namespace NativeXComponentSample
